When snapshot testing (jest snapshot) a component which is connected to redux store I can export the actual component in addition to the connected component
// User.js
/* ... */
export class User extends React.Component {/* ... */}
/* ... */
export default connect(mapStateToProps)(User);
In the test file I can import the actual component (not the connected version) and do snapshot testing on it.
// User.spec.js
import { User } from './User';
/* ... toMatchSnapshot() testing */
But I run into issues when a connected component is nested inside another connected component. For example, let's say User component is nested inside another connected component -
// Wrapper.js
import User from './User'; // importing the connected version
/* ... */
export class Wrapper extends React.Component {
/* ... */
render() {
return (
<div>
/* ... */
<User />
</div>
);
}
}
export default connect(mapStateToProps)(Wrapper);
When running snapshot test on Wrapper the same way I did on User gives me the following error:
Invariant Violation: Could not find "store" in either the context or props of "Connect(User)". Either wrap the root component in a <Provider>, or explicitly pass "store" as a prop to "Connect(User)".`
Is there any way to shallow render when snapshotting? Or am I doing something wrong?
In this case the best way is to test the Wrapper on its own by just mocking User
import Wrapper from './Wrapper'
jest.mock('./User', () => 'User') // note that the path to user is relative the test file not to the Wrapper.js file.
This will replace User with a simple component with name User.
Just a small tweak to the answer provided by @andreas-köberle as it may produce the error: using incorrect casing. Use PascalCase for React components, or lowercase for HTML elements
To fix that if you want to mock a component it should return a fn. Example reflects multi word naming:
jest.mock('./User', () => () => 'UserThingStuff')
or to return an HTML element:
jest.mock('./User', () => 'user-thing-stuff')
You can add Mock store & then test component withougth connect, but with nested connect Components ↓
Component withought connect, but include nested connected Elements ->
test with mocking store, which state can configure.↓ before test : npm install redux-mock-store --save-dev
test.js ↓
import configureStore from "redux-mock-store";
import {Provider} from "react-redux";
//create mockStore
let mockStore;
//create Obj for config store
const mockStoreConf = configureStore([]);
//configure store (add states)
mockStore = mockStoreConf({
someStateInMockStore: `SomeValueFromMockKetInMockStore`,
});
const tree = renderer.create(
<Provider store={mockStore}>
<Component />
</Provider>
);
expect(tree).toMatchSnapshot();
Now your Component's nested connected children take state from your mockStore. Just add needed states on configuration step (//configure store (add states)).
information from https://www.robinwieruch.de/react-connected-component-test